﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Gunningine
{
    /// <summary>
    /// Throw within library code by game mechanic code.
    /// </summary>
    internal class GameException : Exception
    {
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="text">error.</param>
        public GameException(string text)
            : base(text)
        {
        }
    }

    /// <summary>
    /// Thrown when a resource is not found.
    /// </summary>
    internal class ResourceNotFoundException : Exception
    {
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="name">resource name.</param>
        public ResourceNotFoundException(string name)
            : base("Resource '" + name + "' was not found!")
        {
        }
    }

    /// <summary>
    /// Thrown when a resource is can not be loaded, or is corrupt, etc.
    /// </summary>
    internal class ResourceInvalidException : Exception
    {
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="name">resource name.</param>
        public ResourceInvalidException(string name)
            : base("Resource '" + name + "' could not be read!")
        {
        }
    }

    /// <summary>
    /// Thrown when a script fails to compile.
    /// </summary>
    internal class ScriptCompilationException : Exception
    {
        private string[] errors = null;

        public string[] Errors
        {
            get { return this.errors; }
        }

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="errors"></param>
        public ScriptCompilationException(string filename, string[] errors)
            : base("Could not compile '" + filename + "'!")
        {
            this.errors = errors;
        }
    }

    /// <summary>
    /// This is thrown to tell the application to exit.  Yes, I know you 
    /// shouldn't really use exceptions for control flow, but it serves a
    /// useful purpose here.
    /// </summary>
    internal class ExitException : Exception
    {
        public bool Success { get; private set; }

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="success">whether or not the exit was intentional.</param>
        public ExitException(bool success)
            : base()
        {
            this.Success = success;
        }
    }

    /// <summary>
    /// This is thrown by a state when we want to change to a new state.  Doing this
    /// gives us a clean way of backing out of the current state without having to
    /// return esoteric status codes.
    /// </summary>
    internal class ChangeStateException : Exception
    {
        public GameState NextState { get; private set; }

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="nextState">state to change to.</param>
        public ChangeStateException(GameState nextState)
            : base()
        {
            this.NextState = nextState;
        }

        /// <summary>
        /// With no argument, we instead exit the current state.
        /// </summary>
        public ChangeStateException()
            : base()
        {
            this.NextState = null;
        }
    }
}
